// 1.传统并发设计模式
// 对共享内存加锁保证逻辑安全
// 但过度的加锁解锁影响性能,共享内存的关系导致线程之间的耦合度过高

// 2.actor设计模式
// 通过消息传递的方式与外界进行通信, 信息传递的异步的
// actor一次处理一个任务,同时可接收任务消息
// 每一个线程有一个Actor,这些Actor之间通过队列通信(Actor里有队列)
// 这些资源不再是共享的被管理,解耦后的结果就是不会引发许多的线程的感染奔溃

// 3.CSP设计模式
// 顺序通信,两个独立的并发实体通过共享的通信channel进行通信的并发模型
// 发送方给channel,谁要消息就去读取channel => Go语言的channel
// 耦合度更低

// 仿写Go的Channel
#include <condition_variable>
#include <mutex>
#include <queue>
#include <thread>

template <class T>
class Channel {
   private:
    std::mutex _mtx;
    std::queue<T> _massage;
    std::condition_variable _consumer;
    std::condition_variable _producer;
    size_t _capacity;
    bool _close = false;

   public:
    explicit Channel(const size_t capacity = 0) : _capacity(capacity) {}
    bool Send(T value) {
        std::unique_lock<std::mutex> _lock(_mtx);
        // 0:同步发 或者 队列还有存储空间 或者 Channel关闭
        _producer.wait(_lock, [this]() {
            return (_capacity == 0 && _massage.size() == 0) ||
                   _capacity > _massage.size() || _close;
        });

        // 关闭则无法再生产
        if (_close) {
            return false;
        }

        _massage.emplace(value);
        _consumer.notify_one();
        return true;
    }

    bool receive(T& value) {
        std::unique_lock<std::mutex> _lock(_mtx);
        _consumer.wait(_lock, [this]() { return !_massage.empty() || _close; });

        if (_close && _massage.empty()) {
            return false;
        }

        value = _massage.front();
        _massage.pop();
        _producer.notify_one();
        return true;
    }

    void Close() {
        std::unique_lock<std::mutex> _lock(_mtx);
        _close = true;
        _producer.notify_all();
        _consumer.notify_all();
    }
};

// actor与CSP的区别
// actor指定接收发送,CSP谁调用就是谁

int main() { return 0; }